// export the verifyClient at init time for a handshake authentication
const url = require('url')
const { TOKEN_PARAM_NAME } = require('jsonql-constants')
const jwtDecode = require('../../jwt/jwt-decode')
const debug = require('debug')('jsonql-jwt:ws:verify-client')

/**
 * What the name said
 * @param {string} url to decode
 * @return {string} token or nothing means didn't find it
 */
function getTokenFromQuery(_url) {
  const { query } = url.parse(_url)
  const params = query.split('&');
  return params.filter(param => (
      param.indexOf(TOKEN_PARAM_NAME) > -1
    ))
    .reduce((f, n) => n ? n.split('=')[1] : f, false)
}

/**
 * provide the necessary param to create the verifyClient function
 * @param {string|buffer} publicKey for decoding
 * @param {object} [jwtOptions={}] optional pass to the jwtDecode
 * @param {function|boolean} [failCallback=false] if the token is invalid
 * @return {function} verifyClient method
 */
module.exports = function createVerifyClient(publicKey, jwtOptions = {}, failCallback = false) {
  const cb = failCallback === false ? msg => {
    console.error('verifyClient error', msg)
  } : failCallback;
  /**
   * pass this as part of the option to the WebSocket at init time
   * @param {object} info we use the info.req.url to extract the token
   * @param {function} done a callback to pass or fail the login
   */
  return function verifyClient(info, done) {
    let token = getTokenFromQuery(info.req.url)
    if (token) {
      try {
        let payload = jwtDecode(token, publicKey, jwtOptions)
        debug(`calling verifyClient`, payload)
        if (!info.req.state) {
          info.req.state = {};
        }
        // passing this along to the next
        info.req.state.userdata = payload;
        return done(payload)
      } catch(e) {
        done(false)
        cb(e)
      }
    }
    cb('no token!')
    done(false)
  }
}
